package main

import (
	"global/model"
	"global/libs/structs"
	"github.com/ngaut/log"
	"global/core"
	"strings"
	"os"
	"fmt"
	"srv/kline_1min/exchanges/bit-z"
	"srv/kline_1min/exchanges"
	"srv/kline_1min/exchanges/binance"
	"time"
	"srv/kline_1min/exchanges/huobi"
)

type handle struct {
	ctx 			*core.Context
	name 			string
	symbols 		map[string]*structs.Symbol
}

func NewHandle(ctx *core.Context, slug string) *handle {
	h := &handle{
		ctx:		ctx,
		name: 		strings.ToLower(slug),
		symbols:	make(map[string]*structs.Symbol)}
	h.getSymbol()
	return h
}

func (h *handle) run() {
	h.checkDb()
	fmt.Printf("check db complete, symbol length: %d \n", len(h.symbols))
	for _, v := range h.symbols {
		go func(symbol *structs.Symbol) {
			//if symbol.From == "eth" && symbol.To == "btc" {
				h.spider(symbol)
			//}
		}(v)
		time.Sleep(1 * time.Second)
	}
}

func (h *handle) spider(symbol *structs.Symbol) {

	// check history data
	// NeedGetHistory()
	// History()
	// Latest()

	k := h.factory(symbol)
	if k == nil {
		return
	}

	need, err := k.NeedGetHistoryData()
	if err != nil {
		log.Errorf("Error: get history data error, name: %s, symbol: %v, msg: %s", h.name, symbol, err)
		return
	}

	if need {
		fmt.Println("need get history data")
		k.History()
	}

	fmt.Println("get latest data")
	k.Latest()
}

// 获取对象
func (h *handle) factory(symbol *structs.Symbol) exchanges.KlineInterface {
	switch exchange {
	case "bit-z":
		return bit_z.NewBitZKlineHandle(h.name, symbol)
	case "binance":
		return binance.NewBinanceKlineHandle(h.name, symbol)
	case "huobi":
		return huobi.NewHuobiKlineHandle(h.name, symbol)
	}
	return nil
}

// 检查并创建数据表
func (h *handle) checkDb() {
	coins := make(map[string]struct{}, 0)
	for _, v := range h.symbols {
		coins[v.From] = struct{}{}
	}

	for coinName := range coins {
		tableName := fmt.Sprintf("kline_%s", coinName)
		ok, err := model.KlineModel.IsTableExists(tableName)
		if err != nil {
			log.Errorf("check is table exists error: %s", err)
			os.Exit(1)
		}

		if ok {
			continue
		}

		fmt.Println(fmt.Sprintf("%s is not exists", coinName))
		if ok, err := model.KlineModel.CreateTable(tableName); err != nil {
			log.Errorf("create table error: %s", err)
			os.Exit(1)
		} else {
			var msg string
			if ok {
				msg = "create table " + tableName + " success"
			} else {
				msg = "create table " + tableName + " failed"
			}
			fmt.Println(msg)
		}
	}
}

// 加载交易对
func (h *handle) getSymbol() {
	conn := h.ctx.GetBaseRedis().Get()
	defer conn.Close()

	symbols, err := core.GetSymbolsFromExchange(conn, h.name)
	if err != nil {
		log.Errorf("get symbols from exchange failed, error: %s", err)
		os.Exit(1)
	}
	h.symbols = symbols
}
